<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>父子组件的访问方式</title>
</head>
<body>
<!--
■有时候我们需要父组件直接访问子组件子组件直接访问父组件,或者是子组件访问跟组件。
  口父组访问子组件:使用$children或$refs,不过一般$children的方式不建议采用，
  口子组件访问父组件:使用$parent

■我们先来看下$children和$refs的区别
  口this.$children是一个数组类型,它包含所有子组件对象。
  口this.$refs是一个对象类型，每个属性的值对应一个组件对象
  口组件标签上加了ref属性指定的组件对象才能被this.$refs获取到，并且ref的值作为对象属性名，ref所在的组件对象作为属性值一一对应
-->

<div id="app">
  <p style="color: red">this.$children方式调用子组件</p>
  <!--  this.$children方式调用子组件，这种方式会返回一个组件数组，包括所有的父组件下的子组件，一般情况下是不会使用这种方式来操作子组件的，
  因为数组的顺序可能随时都在变，比如我的组件在后续更改中往中间加入了新的组件，或者移除了某个组件，顺序都会发生变化，那么
  如果在之前我们针对某个组件进行了特定操作，顺序一但更改，整个逻辑就变了，所以不推荐-->
  <my-div></my-div>
  <my-div></my-div>
  <br><br>
  <button @click="btnClick">我是父组件按钮点击一下</button>
  <hr>

  <p style="color: red">this.$refs方式调用子组件</p>
  <!--  this.$refs方式调用子组件，必须在组件上加上ref来表明组件标签唯一性，否则通过这种方式是拿不到子组件的，
    而这样设计的好处是，这样不管后续如果表更增加多少个组件标签都不会影响到之前的逻辑，只有加了ref属性指明的才能被
    this.$refs方式获取到，该方式返回的是一个对象，对象中ref的值作为属性名，ref所在的组件对象作为值-->
  <my-div ref="div1"></my-div>
  <my-div ref="div2"></my-div>
  <br><br>
  <button @click="btnClick2" >我是父组件按钮点击一下</button>
  <hr>


</div>

<!--定义模板-->
<template id="myDiv">
  <div>
    <p>我是子组件头</p>
    <p>我是子组件内容</p>
    <button @click="childrenBtnClick">我是子组件按钮点击一下</button>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>

  //构造子组件对象
  const myDiv = {
    template: "#myDiv",
    data() {
      return {
        name: "我是子组件的名字，现在被调用"
      }
    },
    methods: {
      show() {
        console.log("show子组件，子组件方法被调用")
      },
      childrenBtnClick(){
        //访问父组件￥parent
        console.log(this.$parent);
        console.log(this.$parent.name);

        //访问根组件$root
        console.log(this.$root);
        console.log(this.$root.name);
      }
    }
  }

  //根组件
  const app = new Vue({
    el: "#app",
    data: {
      message: "vue app",
      name:"我是根组件，父组件的name，现在被调用"
    },
    //注册局部组件
    components: {
      myDiv
    },
    methods: {
      btnClick() {
        let childrens = this.$children;//拿到组件集合
        childrens.forEach(function (value, index, array) {
          //调用子组件的属性和方法
          console.log(value.name)
          value.show()
        })
      },
      btnClick2() {
        let childrens = this.$refs;//拿到组件集合
        //调用子组件
        console.log(childrens.div1.name)
        childrens.div1.show()
      }
    }
  });
</script>
</body>
</html>